package com.itheima.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.mapper.EmpExprMapper;
import com.itheima.mapper.EmpMapper;
import com.itheima.pojo.*;
import com.itheima.service.DeptService;
import com.itheima.service.EmpExprService;
import com.itheima.service.EmpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Transactional(rollbackFor = Exception.class)
public class EmpServiceImpl extends ServiceImpl<EmpMapper, Emp> implements EmpService {
    @Autowired
    private DeptService deptService;
    @Autowired
    private EmpExprService empExprService;
    @Autowired
    private EmpExprMapper empExprMapper;
    /**
     * 分页查询
     *
     * @param param     查询条件
     * @return 分页结果
     */
    @Override
    public Result pageQuery(EmpQueryParam param) {
       Integer currentPage = param.getPage();
       Integer pageSize = param.getPageSize();
       String name = param.getName();
       Integer gender = param.getGender();
       LocalDate begin = param.getBegin();
       LocalDate end = param.getEnd();
       //创建分页对象,在调用分页查询后，会自动将分页数据封装到page对象中
        Page<Emp> page = Page.of(currentPage,pageSize);
        page.addOrder(OrderItem.desc("update_time"));
        //封装条件,分页查询方法
        this.lambdaQuery()
                .like(StringUtils.isNotBlank(name),Emp::getName,name)
                .eq(!Objects.isNull(gender),Emp::getGender,gender)
                .between(!Objects.isNull(begin) && !Objects.isNull(end),Emp::getEntryDate,begin,end)
                .page(page);
        //分装结果
        List<Dept> depts = deptService.list();
        //将list转换成Map<部门Id,部门名称>
        Map<Long,String> deptMap =depts.stream()
                .collect(Collectors.toMap(Dept::getId,Dept::getName));
        List<Emp> emps = page.getRecords().stream()
                .peek(emp -> emp.setDeptName(deptMap.get(emp.getDeptId())))
                .toList();
        PageResult<Emp> pageResult = new PageResult<>(page.getTotal(),emps);
        return Result.success(pageResult);
    }

    /**
     * 根据id查询员工信息
     *
     * @param id 员工id
     * @return 查询到的员工信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Emp getEmpById(Integer id) {
        Emp emp = getById(id);
        // 工作经历列表
        emp.setExprList(empExprService.list(new LambdaQueryWrapper<EmpExpr>().eq(EmpExpr::getEmpId, id)));
        return emp;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result saveEmpAndExprList(Emp emp) {
      // 保存员工信息
        boolean flag =this.save( emp);
        if(!flag){
            throw new RuntimeException("保存员工信息失败");
        }
        // 保存员工工作经历信息
        List<EmpExpr>exprList = emp.getExprList().stream()
                .peek(expr -> expr.setEmpId(emp.getId()))
                .toList();
        flag =empExprService.saveBatch(exprList);
        if(!flag){
            throw new RuntimeException("保存员工工作经历信息失败");
        }
        return Result.success();
    }

    @Override
    public Result queryEmpAndExprList(Long id) {
    Emp emp = this.getById( id);
    if(!Objects.isNull( emp)){
        emp.setExprList(empExprService.list(new LambdaQueryWrapper<>(EmpExpr.class)
                .eq(EmpExpr::getEmpId, id)
        ));
    }
    return Result.success(emp);
    }


    @Override
    public Result updateEmpAndExprList(Emp emp) {
        emp.setUpdateTime(LocalDateTime.now());
        boolean flag =this.updateById(emp);
        if(!flag){
            throw new RuntimeException("更新员工信息失败");
        }
        //先删除员工工作经历信息
        empExprService.remove(new LambdaQueryWrapper<>(EmpExpr.class).eq(EmpExpr::getEmpId, emp.getId()));
        List<EmpExpr>exprList=emp.getExprList().stream()
                .peek(expr -> expr.setEmpId(emp.getId()))
                .toList();
        flag=empExprService.saveBatch(exprList);
        if(!flag){
            throw new RuntimeException("更新员工工作经历信息失败");
        }
        return Result.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result deleteByIds(List<Integer> ids) {
        // 批量删除员工信息
        boolean flag= this.removeByIds(ids);
        if(!flag){
            throw new RuntimeException("批量删除员工信息失败");
        }
        // 批量删除员工工作经历信息
       try {
           empExprService.remove(new LambdaQueryWrapper<>(EmpExpr.class).in(EmpExpr::getEmpId,ids));
       }catch (Exception e){
           throw new RuntimeException("批量删除员工工作经历信息失败");
       }
        return Result.success();
    }


}